package org.hamster.common.services
{
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.utils.ByteArray;
	
	import mx.rpc.http.HTTPService;
	
	import org.hamster.common.services.events.CacheEvent;
	import org.hamster.common.services.net.CacheURLLoader;

	public class RemoteResourceCacheService extends SimpleCacheService
	{
		protected var listCount:int = -1;
		
		public function RemoteResourceCacheService()
		{
			super();
		}
		
		override public function putItemAsync(key:String, data:*):void
		{
			var urlRequest:URLRequest = new URLRequest(data);
			urlRequest.method = URLRequestMethod.GET;
			var urlLoader:CacheURLLoader = new CacheURLLoader();
			urlLoader.key = key;
			urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
			urlLoader.addEventListener(Event.COMPLETE, loadCompleteHandler);
			urlLoader.addEventListener(IOErrorEvent.IO_ERROR, loadErrorHandler);
			urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, loadErrorHandler);
			urlLoader.load(urlRequest);
		}
		
		private function loadCompleteHandler(event:Event):void
		{
			var urlLoader:CacheURLLoader = CacheURLLoader(event.currentTarget);
			urlLoader.removeEventListener(Event.COMPLETE, loadCompleteHandler);
			urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, loadErrorHandler);
			urlLoader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, loadErrorHandler);
			putItem(urlLoader.key, processResultBinary(urlLoader.data));
			if (this.hasEventListener(CacheEvent.ITEM_LOAD_ASYNC_COMPLETE)) {
				var disEvt:CacheEvent = new CacheEvent(CacheEvent.ITEM_LOAD_ASYNC_COMPLETE);
				disEvt.key 		= urlLoader.key;
				disEvt.value 	= getItem(urlLoader.key);
				this.dispatchEvent(disEvt);
			}
		}
		
		protected function processResultBinary(value:ByteArray):*
		{
			return value;
		}
		
		private function loadErrorHandler(event:Event):void
		{
			var urlLoader:CacheURLLoader = CacheURLLoader(event.currentTarget);
			urlLoader.removeEventListener(Event.COMPLETE, loadCompleteHandler);
			urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, loadErrorHandler);
			urlLoader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, loadErrorHandler);
			if (this.hasEventListener(CacheEvent.ITEM_LOAD_ASYNC_ERROR)) {
				var disEvt:CacheEvent = new CacheEvent(CacheEvent.ITEM_LOAD_ASYNC_COMPLETE);
				disEvt.key 		= urlLoader.key;
				disEvt.value 	= getItem(urlLoader.key);
				this.dispatchEvent(disEvt);
			}
		}
		
		override public function putAllAsync(keyList:Array, dataList:Array):void
		{
			if (listCount == -1) {
				listCount = 0;
			}
			var length:int = Math.min(keyList.length, dataList.length);
			listCount += length;
			for (var i:int = 0; i < length; i++) {
				var urlRequest:URLRequest = new URLRequest(dataList[i]);
				urlRequest.method = URLRequestMethod.GET;
				var urlLoader:CacheURLLoader = new CacheURLLoader();
				urlLoader.isList = true;
				urlLoader.key = keyList[i];
				urlLoaderListInit(urlLoader);
				urlLoader.load(urlRequest);
			}
		}
		
		protected function loadListCompleteHandler(event:Event):void
		{
			listCount--;
			var urlLoader:CacheURLLoader = CacheURLLoader(event.currentTarget);
			urlLoaderListCleanListener(urlLoader);
			putItem(urlLoader.key, processResultBinary(urlLoader.data));
			if (listCount == 0 && this.hasEventListener(CacheEvent.ITEM_LIST_LOAD_ASYNC_COMPLETE)) {
				listCount = -1;
				var disEvt:CacheEvent = new CacheEvent(CacheEvent.ITEM_LIST_LOAD_ASYNC_COMPLETE);
				this.dispatchEvent(disEvt);
			}
		}
		
		protected function loadListErrorHandler(event:Event):void
		{
			listCount--;
			var urlLoader:CacheURLLoader = CacheURLLoader(event.currentTarget);
			urlLoaderListCleanListener(urlLoader);
			if (listCount == 0 && this.hasEventListener(CacheEvent.ITEM_LIST_LOAD_ASYNC_COMPLETE)) {
				listCount = -1;
				var disEvt:CacheEvent = new CacheEvent(CacheEvent.ITEM_LIST_LOAD_ASYNC_COMPLETE);
				this.dispatchEvent(disEvt);
			}
		}
		
		protected function urlLoaderListInit(urlLoader:CacheURLLoader):void
		{
			urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
			urlLoader.addEventListener(Event.COMPLETE, loadListCompleteHandler);
			urlLoader.addEventListener(IOErrorEvent.IO_ERROR, loadListErrorHandler);
			urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, loadListErrorHandler);
		}
		
		protected function urlLoaderListCleanListener(urlLoader:CacheURLLoader):void
		{
			urlLoader.removeEventListener(Event.COMPLETE, loadCompleteHandler);
			urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, loadErrorHandler);
			urlLoader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, loadErrorHandler);
		}
	}
}

